﻿using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using HandyControl.Controls;
using HardToolApp.Model;
using HardToolApp.Tool;
using HardToolApp.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace HardToolApp.ViewModel
{
    [ViewModelHelper("串口", typeof(UartPage), typeof(UartModel), Sort = 2)]
    internal class UartVM : CommVM
    {
        public RelayCommand uartSetParam { get; }
        public RelayCommand uartSendData { get; }

        public UartVM()
        {
            ScriptVM.register("uart_set", "(baud,parity,stopBits,dataLen)", "UART", this.GetType(), "设置串口参数parity:0无，1奇，2偶;stopbits:0一位停止位，1两位停止位;datalen:0:8位，1:9位", "0:操作成功,1:操作失败");
            ScriptVM.register("uart_send", "(发送数据)", "UART", this.GetType(), "发送串口数据", "0:操作成功,1:操作失败");
            ScriptVM.register("uart_rec", "(超时时间ms -1表示无限等待)", "UART", this.GetType(), "接受串口数据", "0:操作成功,1:操作失败");
        }
        // 接收到串口相关
        public override void RecData(byte[] b)
        {
            switch(b[4])
            {
                case (byte)CommSubCmdUart.COMM_SUB_UART_SET_PARAM:
                case (byte)CommSubCmdUart.COMM_SUB_UART_SEND:
                    if (b[5] != (byte)CommStatus.COM_OK)
                    {
                        string str = ((UartModel)Model).cmdName + " " + Communicate.SubString[b[4]] + " " + EnumExtensions.GetDescription((CommStatus)b[5]);
                        Growl.Warning(str, ((UartModel)Model).cmdName);
                    }
                    USBInfoVM.USBVm.AddMap((b[3] << 8) + b[4], b[5]);
                    break;
                case (byte)CommSubCmdUart.COMM_SUB_UART_REC://数据接收
                    ((UartModel)Model).receiveBytes = Common.Byte2String(b.Skip(5).ToArray(),len:b[2]-6);
                    WeakReferenceMessenger.Default.Send(new ReplyClass((byte)CommCmd.COMM_UART, (byte)CommSubCmdUart.COMM_SUB_UART_REC,0));
                    USBInfoVM.USBVm.AddMap((b[3] << 8) + b[4], Common.String2Byte(((UartModel)Model).receiveBytes));
                    break;
            }
        }
        #region Uart
        public static object uart_rec(long timeout)
        {
            return USBInfoVM.USBVm.waitMap.GetValue(((byte)CommCmd.COMM_UART << 8) + (byte)CommSubCmdUart.COMM_SUB_UART_REC, (int)timeout);
        }
        public static object uart_set(long baud,byte parity,byte stopBits,byte dataLen)
        {
            byte[] bytes = new byte[13];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = 13;
            bytes[3] = (byte)CommCmd.COMM_UART;
            bytes[4] = (byte)CommSubCmdUart.COMM_SUB_UART_SET_PARAM;
            bytes[5] = (byte)((baud >> 24) & 0xff);
            bytes[6] = (byte)((baud >> 16) & 0xff);
            bytes[7] = (byte)((baud >> 8) & 0xff);
            bytes[8] = (byte)((baud >> 0) & 0xff);
            bytes[9] = (byte)parity;
            bytes[10] = (byte)stopBits;
            bytes[11] = (byte)dataLen;
            bytes[12] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes);
        }
        public static object uart_send(string sendBytes)
        {
            byte[] data = Common.String2Byte(sendBytes);
            byte[] bytes = new byte[data.Count() + 6];
            bytes[0] = 0x55;
            bytes[1] = 0xaa;
            bytes[2] = (byte)(data.Count() + 6);
            bytes[3] = (byte)CommCmd.COMM_UART;
            bytes[4] = (byte)CommSubCmdUart.COMM_SUB_UART_SEND;
            data.CopyTo(bytes, 5);
            bytes[data.Count() + 5] = Common.chksum(bytes);
            return USBInfoVM.USBVm.send(bytes);
        }
        /// <summary>
        /// 设置串口参数
        /// </summary>
        /// <param name="m"></param>
        public override void Send(Peripheral peripheral)
        {
            UartModel m = (UartModel)peripheral;
            if (m.subCmd == (byte)Communicate.SubCmd.SetParam)
            {
                uart_set(m.baud,(byte)m.parity, (byte)m.stopBits, (byte)m.dataLen);
            }
            else if (m.subCmd == (byte)Communicate.SubCmd.SendData)
            {
                uart_send(m.sendBytes);
            }
        }

        #endregion
    }
}
